<?php
namespace app\websocket\controller;

use app\websocket\model\CustomerOrder;
use app\websocket\model\Order;
use think\Env;
use Workerman\Lib\Timer;
use Workerman\Worker;

$port=Env::get('websocket.port');
global $tcpport;
$tcpport=Env::get('websocket.tcpPort');
require_once ROOT_PATH . 'vendor'.DS.'workerman'.DS.'workerman'.DS.'Autoloader.php';
global $web_worker;
global $request_count;
$request_count=0;
$web_worker = new Worker('websocket://127.0.0.1:'.Env::get('websocket.port',$port));
$web_worker->count = 1;
$web_worker->user='www-data';
echo $web_worker->user.'';
function home_page_data($connection)
{
    $home_sales = CustomerOrder::getCustomerOrderSales($connection->user_id);
    if ($home_sales !== false) {
        $connection->send(json_encode(['code' => 0, 'type' => 'home_sales', 'data' => $home_sales]));
    }
    $home_pay_back = Order::getUserPaidOrderPaidCost($connection->user_id);
    if ($home_pay_back !== false) {
        $connection->send(json_encode(['code' => 0, 'type' => 'home_pay_back', 'data' => $home_pay_back]));
    }
    $home_unpaid_order = Order::getOrderUnpaidNum($connection->user_id);
    if ($home_unpaid_order !== false) {
        $connection->send(json_encode(['code' => 0, 'type' => 'home_unpaid_order', 'data' => $home_unpaid_order]));
    }
    $home_unstock_order = Order::getOrderUnShipNum($connection->user_id);
    if ($home_unstock_order !== false) {
        $connection->send(json_encode(['code' => 0, 'type' => 'home_unstock_order', 'data' => $home_unstock_order]));
    }
    /*    $histogram_data = Order::getOrderHistogramData($connection->user_id);
        if ($histogram_data !== false) {
            $connection->send(json_encode(['code' => 0, 'type' => 'home_option', 'data' => $histogram_data]));
        }
        $polyline_data = CustomerOrder::getCustomerSalesPolyline($connection->user_id);
        if ($polyline_data !== false) {
            $connection->send(json_encode(['code' => 0, 'type' => 'home_sales_data', 'data' => $polyline_data]));
        }*/
}

/**
 * 收到信息
 * @param $connection
 * @param $data
 */
$web_worker->onMessage=function ($connection, $data)
{
    global $web_worker;

    $message = json_decode($data, true);
    if (!$message) {
        $connection->send(json_encode(['code' => 1, 'msg' => '验证错误']));
        return;
    }
    if (!isset($message['type'])) {
        $connection->send(json_encode(['code' => 1, 'msg' => '验证错误']));
        return;
    }
    if ($message['type'] !== 'login' && (!isset($message['token']) || empty($message['token']))) {
        $connection->close(json_encode(['code' => 500, 'msg' => '验证错误']),true);
    }
    $connection->lastMessageTime = time();
    switch ($message['type']) {
        case 'ping':
            $connection->send(json_encode(['code' => 201, 'msg' => 'pong']));
            return;
        case 'login':
            $user = Login::checkLogin($message['message']['user_name'], $message['message']['token']);
            if ($user === false) {
                $connection->close(json_encode(['code' => 500, 'msg' => '验证错误']),true);
            }
            $connection->user_name = $user['user_name'];
            $connection->user_role = $user['role'];
            $connection->user_id = $user['id'];
            $web_worker->uidConnections[$connection->user_id][$connection->id] = $connection;

            home_page_data($connection);
            Timer::add(3600, function () use ($connection) {
                home_page_data($connection);
            });
            $connection->send(json_encode(['code' => 200, 'msg' => '验证通过','id'=>$connection->id]));
            return;
        case 're_refresh_home_data':
            $user = Login::checkLogin($message['message']['user_name'], $message['message']['token']);
            if ($user === false) {
                $connection->close(json_encode(['code' => 500, 'msg' => '验证错误']),true);
            }
            home_page_data($connection);
            return;
        default:
            $connection->send(json_encode(['code' => 1, 'msg' => '错误的消息']));
            return;
    }
};

/**
 * 当连接建立时触发的回调函数
 * @param $connection
 */
$web_worker->onConnect=function($connection)
{
    global $web_worker;
    global $request_count;
    $request_count++;
    echo $request_count;
    if($request_count>1000){
        $web_worker::stopAll();
    }
    $connection->send(json_encode(['code' => 202, 'msg' => '链接已建立']));
};

/**
 * 当连接断开时触发的回调函数
 * @param $connection
 */
$web_worker->onClose=function($connection)
{
    global $web_worker;
    if (isset($connection->user_id)) {
        unset($web_worker->uidConnections[$connection->user_id][$connection->id]);
    }
    $connection->close(json_encode(['code' => 500, 'msg' => '链接已断开']), true);
//    $connection->send(json_encode(['code' => 500, 'msg' => '链接已断开']));
};

/**
 * 当客户端的连接上发生错误时触发
 * @param $connection
 * @param $code
 * @param $msg
 */
$web_worker->onError=function($connection, $code, $msg)
{
    echo "error $code $msg\n";
};

/**
 * 每个进程启动
 * @param $worker
 */
$web_worker->onWorkerStart=function($worker)
{
    global $web_worker;
    global $tcpport;
    $web_worker->uidConnections =[];
    Timer::add(10, function () use ($worker) {
        $time_now = time();
        foreach ($worker->connections as $connection) {
            // 有可能该connection还没收到过消息，则lastMessageTime设置为当前时间
            if (empty($connection->lastMessageTime)) {
                $connection->lastMessageTime = $time_now;
                continue;
            }
            // 上次通讯时间间隔大于心跳间隔，则认为客户端已经下线，关闭连接
            if ($time_now - $connection->lastMessageTime > 60) {
                $connection->close(json_encode(['code' => 500, 'msg' => '心跳已断开']),true);
            }
        }
    });
    $inner_text_worker = new Worker('text://127.0.0.1:'.Env::get('tcpPort',$tcpport));
    $inner_text_worker->onMessage = function ($connection, $buffer) {
        // $data数组格式，里面有uid，表示向那个uid的页面推送数据
        $data = json_decode($buffer, true);
        $uid = $data['uid'];
        $ws_id=$data['ws_id'];
        // 通过workerman，向uid的页面推送数据
        $ret = sendMessageByUid($uid,$ws_id, $data['percent']);
        // 返回推送结果
        $connection->send($ret ? 'ok' : 'fail');
    };
    $inner_text_worker->listen();
};

// 针对uid推送数据
function sendMessageByUid($uid,$ws_id, $message)
{
    global $web_worker;
    foreach ($uid as $key=>$value) {
        if (isset($web_worker->uidConnections[$value])) {
            foreach ($web_worker->uidConnections[$value] as $i => $item) {
                if($i==$ws_id){
                    continue;
                }
                $item->send($message);
            }
        }
    }
    return true;
}

$web_worker::runAll();

